#!/usr/bin/env python

# vPresent is an immersive presentation creation and display application.
# Copyright (C) 2007-2009 by Priority 5 Holdings, Inc.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

import optparse

__build__   = 1
__version__ = "0.1.0.%d" % __build__
__date__    = ' '.join('$Date$'.split()[1:3])
__author__  = 'Priority 5 Holdings, Inc.'
__doc__     = '''This is vPresent. For more information, see the following:
   https://code.google.com/p/vpresent/'''

def processCommandLine():
   parser = optparse.OptionParser(usage = "%prog [ options ... ] [presentation]",
                                  version = __version__,
                                  description = 'vPresent by Priority 5')
   parser.add_option("-p", "--presentation", type = "string",
                     help = "the presentation to load")


   opts, pos_args = parser.parse_args()

   # TODO: Process pos_args
   if len(pos_args) > 0:
      if opts.presentation is not None:
         print "WARNING: Two presentations specified, using:", opts.presentation
      else:
         opts.presentation = pos_args[0]

   return opts

if __name__ == '__main__':
   opts = processCommandLine()

import logging
import mimetypes
import os
import os.path
pj = os.path.join
import sys
from PyQt4 import QtCore, QtGui
import osg2 as osg

import gui.ribbon
import gui.util
import gui.util.environment as environ
import gui.util.xplatform as xplatform
import gui.util.settings as settings

# Set constants right away.
const = gui.util.const
const.APP_NAME     = 'vPresent'
file_dir           = os.path.abspath(os.path.dirname(__file__))
const.EXEC_DIR     = pj(file_dir)
const.DATA_DIR     = pj(file_dir, 'data')
const.SCHEMA_DIR   = const.DATA_DIR
const.VPRESENT_GUI = True
const.VERSION      = __version__

def main():
   # Let PyQt see the command line arguments before OpenSG.
   app = QtGui.QApplication(sys.argv)

   # --- Bootstrap the environment --- #
   logo_path = pj(const.EXEC_DIR, 'gui', 'images', 'vPresentSplash.png')
   splash_map = QtGui.QPixmap(logo_path)
   splash = QtGui.QSplashScreen(splash_map)
   font = QtGui.QFont("Helvetica", 10, QtGui.QFont.Bold)
   splash.setFont(font)
   splash.show()
   splash.showMessage("Loading vPresent by Priority 5",
      QtCore.Qt.AlignRight, QtCore.Qt.white)
   app.processEvents()

   splash.showMessage("Parsing OpenDocument RelaxNG Schema",
      QtCore.Qt.AlignRight, QtCore.Qt.white)
   app.processEvents()

   import opendocument
   opendocument.processRelaxNG()

   splash.showMessage("Processing OpenDocument overrides",
      QtCore.Qt.AlignRight, QtCore.Qt.white)

   # Import all custom OpenDocument data structures.
   for mod in opendocument.NODE_MODULES:
      __import__("opendocument.%s"%(mod))

   splash.showMessage("Initializing OpenSG.",
      QtCore.Qt.AlignRight, QtCore.Qt.white)
   osg.osgInit(sys.argv)

   splash.showMessage("Processing OpenSG overrides",
      QtCore.Qt.AlignRight, QtCore.Qt.white)
   # Import opensg after opendocument.presentation so that all opendocument
   # nodes exist before we try to override/decorate them.
   import gui.opensg

   splash.showMessage("Initializing mime types.",
      QtCore.Qt.AlignRight, QtCore.Qt.white)
   mimetypes.init()

   # Set up logging to sys.stderr.
   fmt_str  = '%(name)-12s %(levelname)-8s %(message)s'
   date_fmt = '%m-%d %H:%M'
   if sys.version_info[0] == 2 and sys.version_info[1] < 4:
      handler = logging.StreamHandler()
      handler.setFormatter(logging.Formatter(fmt_str, date_fmt))
      logger = logging.getLogger('')
      logger.setLevel(logging.DEBUG)
      logger.addHandler(handler)
   else:
      logging.basicConfig(level = logging.DEBUG, format = fmt_str,
                          datefmt = date_fmt)

   if os.environ.has_key('VPRESENT_CFG'):
      site_cfg_file_path = os.environ['VPRESENT_CFG']
   else:
      site_cfg_file_path = pj(const.EXEC_DIR, 'vpresent.xcfg')

   user_cfg_file_name = 'vpresent.xml'
   user_data_dir      = xplatform.getUserAppDir(const.APP_NAME)

   if user_data_dir is not None:
      if not os.path.exists(user_data_dir):
         os.makedirs(user_data_dir)

      user_cfg_file_path = pj(user_data_dir, user_cfg_file_name)
   else:
      user_cfg_file_path = user_cfg_file_name

   splash.showMessage("Loading vPersent settings.",
      QtCore.Qt.AlignRight, QtCore.Qt.white)
   gui_settings = settings.Settings(site_cfg_file_path, user_cfg_file_path,
                                    'vpresent')

   # Load the ribbon description.
   ribbon_mgr = gui.ribbon.UiManager()

   # First access to the Environment singleton.
   environ.Environment().init(gui_settings, ribbon_mgr, opts)

   # XXX: For some reason, the passive window has to be created before the
   # constructor for vPresent is called. Otherwise, a crash occurs when the
   # show() method is invoked on main_window.
   pwin = osg.PassiveWindow.create()

   # This is the first filed container pointer that was created. We need this
   # to skip prototypes in osg.ChangeList.fillFromCurrentState().
   const.FIRST_FC = osg.getContainerId(pwin)

   import gui.vpresent
   main_window = gui.vpresent.vPresent(pwin)
   main_window.init(splash)

   gui_width  = int(gui_settings.getValue('gui_layout/width', 890))
   gui_height = int(gui_settings.getValue('gui_layout/height', 810))
   gui_pos_x  = int(gui_settings.getValue('gui_layout/x', 20))
   gui_pos_y  = int(gui_settings.getValue('gui_layout/y', 55))

   # Close the splash screen.
   splash.finish(None)

   main_window.show()
   main_window.setGeometry(gui_pos_x, gui_pos_y, gui_width, gui_height)

   result = app.exec_()
   logging.shutdown()

   # NOTE: osg.osgExit() is not called here because it causes a crash for
   # some reason. Since it gets called when the process exits (via atexit(3)),
   # that should be good enough.

   sys.exit(result)

if __name__ == '__main__':
   main()
